package cn.codeartist.springboot.component.aop;

import cn.codeartist.springboot.component.util.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.ThrowsAdvice;
import org.springframework.aop.aspectj.AspectJExpressionPointcutAdvisor;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

/**
 * 异常转换切面
 *
 * @author 艾江南
 * @date 2020/9/7
 */
public class ExceptionConvertAspect extends AspectJExpressionPointcutAdvisor {

    private final String expression;

    private final Class<? extends RuntimeException> exception;

    public ExceptionConvertAspect(String expression, Class<? extends RuntimeException> exception) {
        this.expression = expression;
        this.exception = exception;
        init();
    }

    private void init() {
        setExpression(expression);
        setAdvice(new ExceptionConvertAdvice());
    }

    private class ExceptionConvertAdvice implements ThrowsAdvice {

        final private Logger logger = LoggerFactory.getLogger(ExceptionConvertAdvice.class);

        public void afterThrowing(Method method, Object[] args, Object target, Exception e) {
            logger.error("database access error. args:{}", JSON.toJSONString(args), e);
            try {
                Constructor<? extends RuntimeException> constructor = exception.getConstructor(String.class, Throwable.class);
                throw constructor.newInstance(e.getMessage(), e);
            } catch (Exception exception) {
                logger.error("Exception convert error.", e);
            }
        }
    }
}
